/**
 * 
 */
package com.zznode.client.wlanpolling.main;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import javax.xml.xpath.XPathConstants;

import org.apache.log4j.Logger;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.farproc.wifi.connecter.MainActivity;
import com.zznode.client.wlanpolling.EnumRunMode;
import com.zznode.client.wlanpolling.R;
import com.zznode.client.wlanpolling.WLANPollingApplication;
import com.zznode.client.wlanpolling.model.WLANPollManager;
import com.zznode.client.wlanpolling.service.Wifi;
import com.zznode.client.wlanpolling.service.WifiGroup;
import com.zznode.client.wlanpolling.service.net.EnumHttpMethod;
import com.zznode.client.wlanpolling.service.net.HttpExecutorFactory;
import com.zznode.client.wlanpolling.service.net.HttpGetExecutor;
import com.zznode.client.wlanpolling.service.net.HttpParam;
import com.zznode.client.wlanpolling.service.xml.XmlParserException;
import com.zznode.client.wlanpolling.service.xml.XmlXPathAdaptor;
import com.zznode.client.wlanpolling.test.WLANPollingTabActivity;
import com.zznode.client.wlanpolling.utils.PingUtils;
import com.zznode.client.wlanpolling.utils.WLanPollingUtils;
import com.zznode.client.wlanpolling.utils.WifiUtils;
import com.zznode.global.Global;

/**
 * @author Bean AP列表
 */
public class APListActivity2 extends Activity {
	private static Logger logger = Logger.getLogger(APListActivity2.class);

	private ExpandableListView apListView;
	
	private WifiManager mainWifi;
	private WifiReceiver receiverWifi;
	private List<ScanResult> wifiList;
	private WifiManager mWifiManager;

	private WLANPollingApplication application;
	
	/**
	 * 巡检结果已提交的AP
	 */
	private Map<String, String> commitMaps;
	
	private Timer dhcpStatusCheckTimer;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.aplist2);
		
		apListView = (ExpandableListView) findViewById(R.id.apList);
		apListView.setGroupIndicator(null);

		application = (WLANPollingApplication) getApplication();
		mainWifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
		wifiList = new ArrayList<ScanResult>();
		Button btnRescan = (Button)findViewById(R.id.btnRescan);
		btnRescan.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				beignScanAp();
			}
		});
		
		apListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
			
			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				if(groupPosition == 0) {
					Wifi wifi = (Wifi)parent.getExpandableListAdapter().getChild(groupPosition, childPosition);
					if(wifi.getBSSID().equals(application.getContext().getCurrentWifi().getBSSID()) &&
							application.getContext().getCurrentWifi().isSelected()) {
						if(WifiUtils.canUseWifi(mainWifi.getConnectionInfo(), APListActivity2.this)) {
							Intent i = new Intent(APListActivity2.this, WLANPollingTabActivity.class);
							startActivity(i);
						} else {
							Toast.makeText(getApplicationContext(), "正在获取IP地址,请稍候重试！",
									Toast.LENGTH_SHORT).show();
						}
					} else {
						if(application.getContext().getCurrentWifi() != null &&
								application.getContext().getCurrentWifi().isSelected()) {
							application.getContext().getCurrentWifi().setSelected(false);
						}
						
						Global.isclciked = true;
						Global.scanResult = wifi.getScanResult();
						
						final Intent intent = new Intent("com.farproc.wifi.connecter.action.CONNECT_OR_EDIT");
						intent.putExtra("com.farproc.wifi.connecter.extra.HOTSPOT", wifi.getScanResult());
						APListActivity2.this.startActivityForResult(intent, 0);
					}
				} else if(groupPosition >= 2) {
					//切换AP
					if(application.getContext().getCurrentWifi() != null &&
							application.getContext().getCurrentWifi().isSelected()) {
						application.getContext().getCurrentWifi().setSelected(false);
					}
					Wifi wifi = (Wifi)parent.getExpandableListAdapter().getChild(groupPosition, childPosition);
					final Intent intent = new Intent("com.farproc.wifi.connecter.action.CONNECT_OR_EDIT");
					intent.putExtra("com.farproc.wifi.connecter.extra.HOTSPOT", wifi.getScanResult());
					APListActivity2.this.startActivityForResult(intent, 0);
				}
				return true;
			}
		});
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		
		if(receiverWifi == null) {
			receiverWifi = new WifiReceiver();
			
			registerReceiver(receiverWifi, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
			registerReceiver(receiverWifi, new IntentFilter(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION));
			registerReceiver(receiverWifi, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
			registerReceiver(receiverWifi, new IntentFilter(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION));
		}
		
		beignScanAp();
	}

	@Override
	protected void onStop() {
		super.onStop();
		unregisterReceiver(receiverWifi);
		receiverWifi = null;
	}
	
	private void beignScanAp() {
		LinearLayout layoutProgressbar = (LinearLayout)findViewById(R.id.apScanProgressbarLayout);
		layoutProgressbar.setVisibility(View.VISIBLE);
		LinearLayout layoutApListLayout = (LinearLayout)findViewById(R.id.apListLayout);
		layoutApListLayout.setVisibility(View.GONE);
		LinearLayout noApListLayout = (LinearLayout)findViewById(R.id.noApList);
		noApListLayout.setVisibility(View.GONE);
		
		wifiList.clear();
		mainWifi.startScan();
	}

	private void refreshApList() {
		//没有任何接入点
		if(wifiList == null || wifiList.size() == 0) {
			LinearLayout layoutProgressbar = (LinearLayout)findViewById(R.id.apScanProgressbarLayout);
			layoutProgressbar.setVisibility(View.GONE);
			LinearLayout layoutApListLayout = (LinearLayout)findViewById(R.id.apListLayout);
			layoutApListLayout.setVisibility(View.GONE);
			LinearLayout noApListLayout = (LinearLayout)findViewById(R.id.noApList);
			noApListLayout.setVisibility(View.VISIBLE);
			TextView txtNoApMsgTip = (TextView)findViewById(R.id.txtNoApMsgTip);
			txtNoApMsgTip.setText("当前无可用的无线网络");
			
			return;
		} 
		
		LinearLayout layoutProgressbar = (LinearLayout)findViewById(R.id.apScanProgressbarLayout);
		layoutProgressbar.setVisibility(View.GONE);
		LinearLayout noApListLayout = (LinearLayout)findViewById(R.id.noApList);
		noApListLayout.setVisibility(View.GONE);
		LinearLayout layoutApListLayout = (LinearLayout)findViewById(R.id.apListLayout);
		layoutApListLayout.setVisibility(View.VISIBLE);
		
		// for phone
		WifiInfo wifiInfo = mainWifi.getConnectionInfo();
		//已测试的AP Mac集合
		Set<String> testedApMacs = WLANPollManager.getWLANPollManager().getTestApSet(application.getApplicationContext());
		Map<String, WifiGroup> wifiGroups = application.getContext().getApGroupList();
		wifiGroups.clear();
		application.getContext().setCurrentWifi(null);
		
		//数据提取
		for (ScanResult result : wifiList) {
			Wifi wifi = null;
			if (result.SSID == null) {
				result.SSID = "未知";
			}
			if (result.BSSID.equals(wifiInfo.getBSSID())) {
				wifi = new Wifi(result, wifiInfo);
				wifi.setSelected(true);
				application.getContext().setCurrentWifi(wifi);
			} else {
				wifi = new Wifi(result, null);
				wifi.setSelected(false);
			}
			
			String currAp = PingUtils.clearMacAdress(wifi.getBSSID());
			if(testedApMacs.contains(currAp)) {
				wifi.setTested(true);
			} else {
				wifi.setTested(false);
			}
			
			if(commitMaps != null) {
				if("1".equals(commitMaps.get(PingUtils.clearMacAdress(wifi.getBSSID()).toLowerCase()))) {
					wifi.setCommited(true);
				} else {
					wifi.setCommited(false);
				}
			} else {
				wifi.setCommited(false);
			}
			
			WifiGroup wifiGroup = (WifiGroup) wifiGroups.get(wifi.getSSID());
			if (wifiGroup == null) {
				wifiGroup = new WifiGroup(wifi.getSSID());
				wifiGroups.put(wifi.getSSID(), wifiGroup);
			}
			wifiGroup.addWifi(wifi);
		}

		//当前无线接入点
		GroupWifi currGroupWifi = null;

		if (application.getContext().getCurrentWifi() != null) {
			//加载当前AP上次的测试结果
			WLANPollManager.getWLANPollManager().loadTestResultFromDb(application.getApplicationContext(),
					PingUtils.clearMacAdress(application.getContext().getCurrentWifi().getBSSID()));

			WifiGroup wifiGroup = wifiGroups.get(application.getContext()
					.getCurrentWifi().getSSID());

			List<Wifi> aplist = new ArrayList<Wifi>();
			for (Wifi wifi : wifiGroup.getApList()) {
				if (application.getContext().getCurrentWifi().getBSSID()
						.equals(wifi.getBSSID())) {
					wifi.setOpened(true);
					
				} else {
					wifi.setOpened(false);
				}
				aplist.add(wifi);
			}
			currGroupWifi = new GroupWifi(wifiGroup.getSSID(), wifiGroup.getApList());
		}
		
		//其他无线接入点
		List<GroupWifi> otherGroupWifies = new ArrayList<GroupWifi>();
		
		for (WifiGroup wifiGroup : wifiGroups.values()) {
			if (application.getContext().getCurrentWifi() != null && wifiGroup.getSSID()!=null && !wifiGroup.getSSID().equals(
					application.getContext().getCurrentWifi().getSSID()) || application.getContext().getCurrentWifi() == null) {
				for (Wifi wifi : wifiGroup.getApList()) {
					wifi.setOpened(false);
				}
				
				GroupWifi groupWifi = new GroupWifi(wifiGroup.getSSID(), wifiGroup.getApList());
				otherGroupWifies.add(groupWifi);
			}
		}
		
		APList2Adaptor apList2Adaptor = new APList2Adaptor(APListActivity2.this, currGroupWifi, otherGroupWifies);
		apListView.setAdapter(apList2Adaptor);
		
		int groupCount = apList2Adaptor.getGroupCount();
		for(int i = 0; i < groupCount; i++){
			apListView.expandGroup(i);
		}
	}

	@Override
	protected void onActivityResult(int requestCode, final int resultCode, Intent data) {
		if(requestCode == 0) {
			if(resultCode == Activity.RESULT_OK) {
				//start a timer to check dhcp is completed.
				//切换接入点
				logger.debug("Switch AP:" + application.getContext().getCurrentWifi());
			} {
				if(application.getContext().getCurrentWifi() != null &&
						application.getContext().getCurrentWifi().isSelected()) {
					application.getContext().getCurrentWifi().setSelected(true);
				}
			}
			if(resultCode == Activity.RESULT_CANCELED){
				if(application.getContext().getCurrentWifi() != null &&
						!application.getContext().getCurrentWifi().isSelected()) {
					application.getContext().getCurrentWifi().setSelected(true);
				}
			}
		}
	}
	
	/**
	 * 监听网络状态变化的通知和扫面AP列表的通知
	 * @author Bean
	 *
	 */
	class WifiReceiver extends BroadcastReceiver {
		public void onReceive(Context c, Intent intent) {
			final String action = intent.getAction();
			Log.d(WifiReceiver.class.getName(), WifiUtils.getNetworkIpAddress(APListActivity2.this));
			WifiInfo wifiInfo = null;
			if(mainWifi.getConnectionInfo()!=null)
			  wifiInfo = mainWifi.getConnectionInfo();
			
			if(action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
				if(intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
					AlertDialog.Builder builder = new AlertDialog.Builder(APListActivity2.this);
					
					builder.setMessage("WIFI重新连接,是否需要重新扫描周围列表并和服务器进行同步?")
					.setCancelable(true).
					setPositiveButton("刷新", new DialogInterface.OnClickListener(){
						@Override
						public void onClick(DialogInterface dialog, int which) {
							beignScanAp();
						}
					}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface dialog, int which) {
							dialog.cancel();
						}
					});
					
					builder.show();
				}
			}
			
			if(action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
				logger.debug("AP SCAN_RESULTS_AVAILABLE_ACTION:" + application.getContext().getCurrentWifi());
				
				wifiList = mainWifi.getScanResults();
				Log.d(APListActivity2.class.getName(), "WifiManager.SCAN_RESULTS_AVAILABLE_ACTION");
				refreshApList();
				
			}
			
			if(action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
				
				SupplicantState state = (SupplicantState)intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
				if(wifiInfo.getBSSID()!=null)
					Log.d(APListActivity2.class.getName(),"test by sv--------------WifiManager.SUPPLICANT_STATE_CHANGED_ACTION , "+wifiInfo.getBSSID());
				else {
					Log.d(APListActivity2.class.getName(),"test by sv--------------WifiManager.SUPPLICANT_STATE_CHANGED_ACTION is null " );
				}
				if(state != null) {
					Log.d(APListActivity2.class.getName(), "WifiManager.SUPPLICANT_STATE_CHANGED_ACTION , " + state.toString());
				} else {
					Log.d(APListActivity2.class.getName(), "WifiManager.SUPPLICANT_STATE_CHANGED_ACTION");
				}
				if(state == SupplicantState.COMPLETED) {
					logger.debug("AP SupplicantState.COMPLETED:" + application.getContext().getCurrentWifi());
					wifiList = mainWifi.getScanResults();
					refreshApList();
					
					try {
						if (wifiInfo.getBSSID()!=null) {
							if (Global.scanResult !=null && !Global.scanResult.BSSID.equals(wifiInfo.getBSSID()) && Global.isclciked) {
								logger.debug("切换ap失败！");
							}
							else if (Global.scanResult !=null && Global.scanResult.BSSID.equals(wifiInfo.getBSSID()) && Global.isclciked) {
								logger.debug("切换ap成功！");
							}
							logger.debug("当前连接的ap的mac："+application.getContext().getCurrentWifi().getBSSID());
						} 
					} catch (Exception e) {
						// TODO: handle exception
					}
					Global.isclciked = false;
					if(wifiInfo.getBSSID()!=null)
						logger.debug("test by sv--------------WifiManager.SUPPLICANT_STATE_CHANGED_ACTION , "+wifiInfo.getBSSID());
					else {
						logger.debug("test by sv--------------WifiManager.SUPPLICANT_STATE_CHANGED_ACTION is null ");
					}
					logger.debug("svenke  AP SupplicantState.COMPLETED:" + application.getContext().getCurrentWifi());
//					System.err.println("WifiManager.SUPPLICANT_STATE_CHANGED_ACTION curr ap bssid :" + info.getBSSID());
					TimerTask task = new DhcpStatusCheckTimerTask();
					dhcpStatusCheckTimer = new Timer();
					dhcpStatusCheckTimer.schedule(task, 1000, 1000);
				}
			}
			
			if(action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
				Log.d(APListActivity2.class.getName(), "WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION");
				logger.debug("!!WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION!!" );
				System.err.println("!!WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION!!");
				refreshApList();
			}
			
			if(action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
				Log.d(APListActivity2.class.getName(), "WifiManager.WIFI_STATE_CHANGED_ACTION");
			}
		}
	}

	@Override
	public void onBackPressed() {
		if(getParent() instanceof MainTabActivity) {
			getParent().onBackPressed();
		} else {
			super.onBackPressed();
		}
	}
	
	/**
	 * 加载巡检计划数据
	 */
	private void loadPlanData() {
		if(!WifiUtils.canUseWifi(mainWifi.getConnectionInfo(), APListActivity2.this)) {
			return;
		}
		
		if(wifiList == null || wifiList.size() == 0)
			return;
		
		//获取巡检计划
		StringBuffer bssids = new StringBuffer();
		StringBuffer ssids = new StringBuffer();
		
		for(int i = 0; i < wifiList.size(); i++) {
			ScanResult sr = wifiList.get(i);
			String bssid = "";
			if(WLanPollingUtils.RUN_MODE == EnumRunMode.DEBUG) {
				bssid = WLanPollingUtils.DEBUG_WIFI;
			} else {
				bssid = sr.BSSID;
			}
			
			bssids.append(PingUtils.clearMacAdress(bssid) + ",");
			ssids.append(sr.SSID + ",");
		}
		
		bssids.deleteCharAt(bssids.length()-1);
		ssids.deleteCharAt(ssids.length() - 1);
		
		HttpGetExecutor executor = (HttpGetExecutor) HttpExecutorFactory.createHttpExecutor(EnumHttpMethod.GET);
		executor.setUrl(WLanPollingUtils.getPlanURL());
		executor.addParam(new HttpParam("onLineApInfo", bssids.toString()));
		executor.addParam(new HttpParam("ssids", ssids.toString()));
		
		XmlXPathAdaptor xPath = null;
		try {
			byte[] bytes = executor.syncExecute();
			xPath = new XmlXPathAdaptor(new ByteArrayInputStream(bytes));
		} catch (final Exception e) {
			logger.error(e.getMessage(), e);
			runOnUiThread(new Runnable() {
				
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), e.getMessage(),
							Toast.LENGTH_SHORT).show();
				}
			});
		}
		
		if(xPath != null) {
			commitMaps = new HashMap<String, String>();
			
			NodeList nodes = null;
			try {
				nodes = (NodeList)xPath.evaluate("/NODE/ID", XPathConstants.NODESET);
			} catch (final XmlParserException e) {
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						Toast.makeText(getApplicationContext(), e.getMessage(),
								Toast.LENGTH_SHORT).show();
					}
				});
			}
			
			if(nodes != null) {
				if(nodes != null && nodes.getLength() > 0) {
					for(int i = 0; i < nodes.getLength(); i++) {
						Node node = nodes.item(i);
						String bssid = node.getAttributes().getNamedItem("AP_MAC").getNodeValue();
						String status = node.getTextContent();
						if(bssid != null && status != null) {
							Log.d("test", "bssid=" + bssid + ", status=" + status);
							commitMaps.put(PingUtils.clearMacAdress(bssid).toLowerCase(), status);
						}
					}	
				}
			}
		}
	}
	
	class DhcpStatusCheckTimerTask extends TimerTask {
		@Override
		public void run() {
			String ip = WifiUtils.getNetworkIpAddress(APListActivity2.this);
			if(!ip.equals("0.0.0.0")) {
				Log.d(DhcpStatusCheckTimerTask.class.getName(), ip);
				dhcpStatusCheckTimer.cancel();
				dhcpStatusCheckTimer = null;
				Message msg = new Message();
				msg.what = 1;
				refreshHandler.sendMessage(msg);
			} else {
				Log.d(DhcpStatusCheckTimerTask.class.getName(), "--" + ip);
			}
		}
	}
	
	private Handler refreshHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			if(msg.what == 1) {
				loadPlanData();
				refreshApList();
			}
			super.handleMessage(msg);
		}
	};
}
